 package com.oanda.blackberry.view;
 
 import com.oanda.blackberry.OandaBlackBerryApplication;
 import com.oanda.blackberry.restapi.Quote;
 import com.oanda.blackberry.restapi.Symbol;
 import com.oanda.blackberry.restapi.TradeOrder;
 import com.oanda.blackberry.restapi.TradeOrderResponse;
 import com.oanda.blackberry.ui.BitmapButtonField;
 import com.oanda.blackberry.ui.ColoredEditField;
 import com.oanda.blackberry.ui.ColoredObjectChoiceField;
 import com.oanda.blackberry.ui.CustomBitmapField;
 import com.oanda.blackberry.ui.OandaMainScreen;
 import com.oanda.blackberry.ui.QuoteChangeListener;
 import com.oanda.blackberry.ui.QuoteEditField;
 import com.oanda.blackberry.ui.SpacerField;
 import com.oanda.blackberry.ui.SpacerManager;
 import com.oanda.blackberry.ui.TradeLimitEditField;
 import com.oanda.blackberry.ui.TradeTypeChangeListener;
 import com.oanda.blackberry.util.AbstractViewPanel;
 import com.oanda.blackberry.util.DefaultController;
 import com.oanda.blackberry.util.Model;
 import com.oanda.blackberry.util.PropertyChangeEvent;
 import com.oanda.blackberry.util.log.Logger;
 import java.util.Timer;
 import java.util.TimerTask;
 import java.util.Vector;
 import net.rim.device.api.system.Application;
 import net.rim.device.api.system.Bitmap;
 import net.rim.device.api.ui.Field;
 import net.rim.device.api.ui.FieldChangeListener;
 import net.rim.device.api.ui.Font;
 import net.rim.device.api.ui.Manager;
 import net.rim.device.api.ui.MenuItem;
 import net.rim.device.api.ui.Screen;
 import net.rim.device.api.ui.UiApplication;
 import net.rim.device.api.ui.component.BasicEditField;
 import net.rim.device.api.ui.component.ChoiceField;
 import net.rim.device.api.ui.component.Dialog;
 import net.rim.device.api.ui.component.Menu;
 import net.rim.device.api.ui.component.ObjectChoiceField;
 import net.rim.device.api.ui.component.RadioButtonField;
 import net.rim.device.api.ui.component.RadioButtonGroup;
 import net.rim.device.api.ui.container.HorizontalFieldManager;
 import net.rim.device.api.ui.container.MainScreen;
 import net.rim.device.api.ui.decor.BackgroundFactory;
 
 public class NewTradeView
   implements AbstractViewPanel
 {
   DefaultController controller;
   BitmapButtonField submit;
   ColoredObjectChoiceField symbol = new ColoredObjectChoiceField(16119285, "", null, 100, 23);
   QuoteEditField quoteField = new QuoteEditField(0L, null, 0);
   RadioButtonGroup sellBuyGroup;
   HorizontalFieldManager operationFieldManager;
   RadioButtonField buy;
   RadioButtonField sell;
   ColoredEditField units;
   TradeLimitEditField tp;
   TradeLimitEditField sl;
   TradeLimitEditField ts;
   TradeLimitEditField lb;
   TradeLimitEditField ub;
   OandaMainScreen screen;
   CustomBitmapField c1;
   CustomBitmapField c2;
   CustomBitmapField c3;
   CustomBitmapField c4;
   CustomBitmapField c5;
   Vector tradeTypeChangeListeners = new Vector();
   Vector quoteChangeListeners = new Vector();
   static final int UPDATE_TIME_QUOTE = 5000;
   Timer quoteTimer = new Timer();
 
   TimerTask quoteTask = new TimerTask() {
     public synchronized void run() {
       if (OandaBlackBerryApplication.isInForeground)
       {
         NewTradeView.this.quoteUpdates();
       }
       else
       {
         try
         {
           wait();
         }
         catch (InterruptedException e)
         {
         }
       }
     }
   };
 
   MenuItem submitMenu = new MenuItem("Submit", 10, 1000)
   {
     public void run() {
       NewTradeView.this.submit();
     }
   };
 
   MenuItem back = new MenuItem("Back", 10, 1001)
   {
     public void run() {
       NewTradeView.this.onClose();
     }
   };
 
   public void notifyTimerTask()
   {
     if (this.quoteTask != null)
     {
       synchronized (this.quoteTask)
       {
         this.quoteTask.notifyAll();
       }
     }
   }
 
   public NewTradeView(DefaultController controller) {
     this.controller = controller;
   }
 
   private boolean validateTrade() {
     return false;
   }
 
   private void symbolFieldChanged()
   {
     if (this.symbol == null) return;
 
     int selected = this.symbol.getSelectedIndex();
     if ((selected > -1) && (this.symbol.getChoice(selected) != null) && 
       ((this.symbol.getChoice(selected) instanceof Quote))) {
       Quote q = (Quote)this.symbol.getChoice(selected);
 
       this.quoteField.setQuote(q);
       notifyQuoteChangeListeners(q);
       this.screen.invalidate();
     }
   }
 
   private void tradeTypeChanged(String type)
   {
     notifyTradeTypeListeners(type);
   }
 
   private void notifyQuoteChangeListeners(Quote quote) {
     for (int i = 0; i < this.quoteChangeListeners.size(); i++) {
       QuoteChangeListener object = (QuoteChangeListener)this.quoteChangeListeners.elementAt(i);
       object.setQuote(quote);
     }
   }
 
   private void notifyTradeTypeListeners(String type) {
     for (int i = 0; i < this.tradeTypeChangeListeners.size(); i++) {
       TradeTypeChangeListener object = (TradeTypeChangeListener)this.tradeTypeChangeListeners.elementAt(i);
       object.setTradeType(type);
     }
   }
 
   private void submit()
   {
     Quote quote = Model.getModel().getRateQuotes()[this.symbol.getSelectedIndex()];
     if (quote == null) {
       DefaultController.inform("Unable to get the required symbol!");
       return;
     }
 
     String unitsValue = this.units.getText();
     int u = 0;
     if ((unitsValue == null) || ((unitsValue != null) && (unitsValue.length() == 0))) {
       DefaultController.inform("Error: Units must be greater than 0");
       return;
     }
     try {
       u = Integer.parseInt(unitsValue);
     }
     catch (NumberFormatException ne)
     {
     }
     if (4 != Dialog.ask(3, "Are you sure you want to create a new trade?")) {
       return;
     }
 
     double rate = 0.0D;
     String type = "";
     String tradeType = "";
     if (this.sellBuyGroup.getSelectedIndex() == 0) {
       rate = quote.getBid();
       type = "sell";
       tradeType = "short";
     }
     else {
       rate = quote.getAsk();
       type = "buy";
       tradeType = "long";
     }
 
     String lowerPrice = this.lb.getText();
     double lP = (0.0D / 0.0D);
     if ((lowerPrice != null) && (lowerPrice.length() > 0))
       try {
         lP = Double.parseDouble(lowerPrice);
       } catch (NumberFormatException ne) {
         DefaultController.inform("error in parsing lower bound to double");
       }
     else {
       lowerPrice = "";
     }
 
     String highPrice = this.ub.getText();
     double uP = (0.0D / 0.0D);
     if ((highPrice != null) && (highPrice.length() > 0))
       try {
         uP = Double.parseDouble(highPrice);
       } catch (NumberFormatException ne) {
         DefaultController.inform("error in parsing upper bound to double");
       }
     else {
       highPrice = "";
     }
 
     String stopLoss = this.sl.getText();
     double sL = (0.0D / 0.0D);
     if ((stopLoss != null) && (stopLoss.length() > 0))
       try {
         sL = Double.parseDouble(stopLoss);
       } catch (NumberFormatException ne) {
         DefaultController.inform("error in parsing stop loss to double");
       }
     else {
       stopLoss = "";
     }
 
     String takeProfit = this.tp.getText();
     double tP = (0.0D / 0.0D);
     if ((takeProfit != null) && (takeProfit.length() > 0))
       try {
         tP = Double.parseDouble(takeProfit);
       } catch (NumberFormatException ne) {
         DefaultController.inform("error in parsing takeProfit to double");
       }
     else {
       takeProfit = "";
     }
 
     String trailingStop = this.ts.getText();
     double tS = (0.0D / 0.0D);
     if ((trailingStop != null) && (trailingStop.length() > 0))
       try {
         tS = Double.parseDouble(trailingStop);
       } catch (NumberFormatException ne) {
         DefaultController.inform("error in parsing trailingStop to double");
       }
     else {
       trailingStop = "";
     }
 
     Symbol symbol = Model.getModel().getSymbol(quote.getSymbol());
     if (symbol == null) {
       DefaultController.inform("unable to find the symbol for the given quote.");
       return;
     }
 
     double pipLoc = symbol.getPiploc();
 
     if (tS != (0.0D / 0.0D))
     {
       if (tS < 10.0D) {
         DefaultController.inform("Error: Trailng Stop must be at least 10 pips");
         return;
       }
 
       int intTS = 0;
       intTS = (int)symbol.getPippettes(tS);
       trailingStop = Integer.toString(intTS);
     }
 
     TradeOrder order = new TradeOrder(quote.getSymbol(), u, Model.getModel().getActiveAccountId(), type, rate, lP, uP, sL, tP, tS, tradeType, pipLoc);
 
     String validationMessage = order.validate();
     if ((validationMessage != null) && (validationMessage.length() > 0))
     {
       DefaultController.inform(validationMessage);
       return;
     }
 
     this.controller.tradeOrder(quote.getSymbol(), unitsValue, Model.getModel().getActiveAccountId(), type, Double.toString(rate), lowerPrice, highPrice, stopLoss, takeProfit, trailingStop);
   }
 
   private void setQuotes(final Quote[] quote)
   {
     if (quote == null) return;
     if ((quote != null) && (quote.length == 0)) return;
		UiApplication.getUiApplication().invokeLater(new Runnable() {
			private final Quote[] _quote = quote;
 
       public void run() { if ((NewTradeView.this.symbol != null) && (NewTradeView.this.quoteField != null) && (NewTradeView.this.screen != null)) {
           int selected = NewTradeView.this.symbol.getSelectedIndex();
           if (selected == -1) selected = 0;
           NewTradeView.this.symbol.setChoices(this._quote);
 
           if (this._quote.length > selected) {
             NewTradeView.this.symbol.setSelectedIndex(selected);
             NewTradeView.this.quoteField.setQuote(this._quote[selected]);
             NewTradeView.this.screen.invalidate();
           }
         }
       }
     });
   }
 
   private void setTradeDetails(final Quote quote)
   {
     if (quote == null) return;
 
     UiApplication.getUiApplication().invokeLater(new Runnable() {
       private final Quote _quote=quote;
 
       public void run() { NewTradeView.this.units.setText("");
         if (this._quote.isBuy()) {
           NewTradeView.this.sellBuyGroup.setSelectedIndex(1);
         }
         else {
           NewTradeView.this.sellBuyGroup.setSelectedIndex(0);
         }
 
         NewTradeView.this.setSelectedQuote(this._quote.getSymbol());
       }
     });
   }
 
   public void modelPropertyChange(PropertyChangeEvent evt)
   {
     if (evt.getPropertyName().equals("setTradeOrderResponse")) {
       if ((evt.getNewValue() instanceof TradeOrderResponse)) {
         TradeOrderResponse response = (TradeOrderResponse)evt.getNewValue();
         DefaultController.showMessage("Trade executed." + (response.getDir().equalsIgnoreCase("L") ? "\nBought " : "\nSold ") + String.valueOf(response.getUnits()) + " units of " + response.getSymbol() + " at " + String.valueOf(new StringBuffer().append(response.getPrice()).append(". Margin used ").append(Double.toString(response.getMargin())).append(".").toString()));
 
         Runnable r = new Runnable()
         {
           public void run()
           {
             NewTradeView.this.onClose();
           }
         };
         this.controller.invokeLater(r);
       } else {
         DefaultController.inform("Unable to parse TradeOrderResponse");
       }
     }
     else if (evt.getPropertyName().equals("newTradeOpenBuy")) {
       init();
       setQuotes(Model.getModel().getRateQuotes());
       this.controller.pushScreen(this.screen);
       startQuoteUpdateThread();
       if (evt.getNewValue() != null)
         setTradeDetails((Quote)evt.getNewValue());
     }
     else if (evt.getPropertyName().equals("newTradeOpenSell")) {
       init();
       setQuotes(Model.getModel().getRateQuotes());
       this.controller.pushScreen(this.screen);
       startQuoteUpdateThread();
       if (evt.getNewValue() != null)
         setTradeDetails((Quote)evt.getNewValue());
     }
   }
 
   private void init()
   {
     this.screen = new OandaMainScreen() {
       protected void makeMenu(Menu menu, int instance) {
         menu.add(NewTradeView.this.submitMenu);
         menu.add(NewTradeView.this.back);
       }
     };
     this.screen.getTitleManager().deleteAll();
 
     Bitmap bg = Bitmap.getBitmapResource("newtrade-bg-480x400b.png");
     this.screen.getMainManager().setBackground(BackgroundFactory.createBitmapBackground(bg));
 
     createFields();
 
     setFonts();
     setBorders();
 
     this.sellBuyGroup.add(this.sell);
     this.sellBuyGroup.add(this.buy);
 
     this.screen.add(new SpacerField(480, 47));
     HorizontalFieldManager quoteM = new HorizontalFieldManager();
     this.symbol.setMargin(1, 0, 0, 10);
     quoteM.add(this.symbol);
     quoteM.add(this.quoteField);
     this.screen.add(quoteM);
 
     this.screen.add(new SpacerField(480, 3));
 
     this.operationFieldManager.add(new SpacerField(140, 12));
     this.operationFieldManager.add(this.sell);
     this.operationFieldManager.add(new SpacerField(84, 12));
     this.operationFieldManager.add(this.buy);
     this.screen.add(this.operationFieldManager);
 
     this.screen.add(new SpacerField(480, 8));
 
     this.units.setMargin(5, 120, 0, 78);
 
     HorizontalFieldManager unitsM = new HorizontalFieldManager();
     unitsM.add(this.units);
     this.screen.add(unitsM);
 
     this.screen.add(new SpacerField(480, 18));
 
     HorizontalFieldManager limits = new HorizontalFieldManager(1152921504606846976L);
     SpacerManager v0LeftMargin = new SpacerManager(20, 102);
     SpacerManager v0 = new SpacerManager(20, 102);
     v0LeftMargin.setFocusable(false);
     v0.setFocusable(false);
     SpacerManager v1 = new SpacerManager(200, 102);
 
     SpacerManager v1RightMargin = new SpacerManager(20, 102);
     SpacerManager v11 = new SpacerManager(20, 102);
     SpacerManager v2 = new SpacerManager(200, 102);
     v1RightMargin.setFocusable(false);
     v11.setFocusable(false);
 
     v0LeftMargin.add(new SpacerField(20, 1));
     v1RightMargin.add(new SpacerField(20, 1));
 
     limits.add(v0LeftMargin);
     limits.add(v0);
     limits.add(v1);
 
     limits.add(v1RightMargin);
     limits.add(v11);
     limits.add(v2);
     this.screen.add(limits);
 
     this.tp.setTradeLimitType(0);
     this.ts.setTradeLimitType(2);
     this.ub.setTradeLimitType(3);
     this.sl.setTradeLimitType(1);
     this.lb.setTradeLimitType(4);
 
     this.tp.setMargin(0, 0, 0, 40);
     this.sl.setMargin(16, 0, 0, 40);
     this.ts.setMargin(14, 0, 0, 40);
     this.ub.setMargin(0, 0, 0, 40);
     this.lb.setMargin(16, 0, 0, 40);
 
     this.c1 = new CustomBitmapField(Bitmap.getBitmapResource("symbol-selected-18x18-p24.png"), Bitmap.getBitmapResource("symbol-notselected-18x18.png"), "", 45035996273704960L);
 
     this.c2 = new CustomBitmapField(Bitmap.getBitmapResource("symbol-selected-18x18-p24.png"), Bitmap.getBitmapResource("symbol-notselected-18x18.png"), "", 9007199254740992L);
 
     this.c2 = new CustomBitmapField(Bitmap.getBitmapResource("symbol-selected-18x18-p24.png"), Bitmap.getBitmapResource("symbol-notselected-18x18.png"), "", 9007199254740992L);
 
     this.c3 = new CustomBitmapField(Bitmap.getBitmapResource("symbol-selected-18x18-p24.png"), Bitmap.getBitmapResource("symbol-notselected-18x18.png"), "", 9007199254740992L);
 
     this.c4 = new CustomBitmapField(Bitmap.getBitmapResource("symbol-selected-18x18-p24.png"), Bitmap.getBitmapResource("symbol-notselected-18x18.png"), "", 9007199254740992L);
 
     this.c5 = new CustomBitmapField(Bitmap.getBitmapResource("symbol-selected-18x18-p24.png"), Bitmap.getBitmapResource("symbol-notselected-18x18.png"), "", 9007199254740992L);
 
     this.c2.setMargin(18, 0, 0, 0);
     this.c3.setMargin(16, 0, 0, 0);
     this.c5.setMargin(17, 0, 0, 0);
 
     v0.add(this.c1);
     v0.add(this.c2);
     v0.add(this.c3);
     v11.add(this.c4);
     v11.add(this.c5);
 
     this.tp.setActiveListener(this.c1);
     this.sl.setActiveListener(this.c2);
     this.ts.setActiveListener(this.c3);
     this.ub.setActiveListener(this.c4);
     this.lb.setActiveListener(this.c5);
 
     this.tradeTypeChangeListeners = new Vector();
     this.quoteChangeListeners = new Vector();
 
     this.tradeTypeChangeListeners.addElement(this.tp);
     this.quoteChangeListeners.addElement(this.tp);
     this.tradeTypeChangeListeners.addElement(this.sl);
     this.quoteChangeListeners.addElement(this.sl);
     this.tradeTypeChangeListeners.addElement(this.ub);
     this.quoteChangeListeners.addElement(this.ub);
     this.tradeTypeChangeListeners.addElement(this.lb);
     this.quoteChangeListeners.addElement(this.lb);
     this.tradeTypeChangeListeners.addElement(this.ts);
     this.quoteChangeListeners.addElement(this.ts);
 
     v1.add(this.tp);
     v1.add(this.sl);
     v1.add(this.ts);
 
     v2.add(this.ub);
     v2.add(this.lb);
 
     this.screen.add(new SpacerField(480, 3));
 
     this.screen.add(this.submit);
 
     this.submit.setMargin(4, 0, 0, 0);
 
     this.submit.setChangeListener(new FieldChangeListener()
     {
       public void fieldChanged(Field field, int context)
       {
         NewTradeView.this.submit();
       }
     });
     this.quoteField.setChangeListener(new FieldChangeListener()
     {
       public void fieldChanged(Field field, int context)
       {
         if ((NewTradeView.this.symbol != null) && (NewTradeView.this.symbol.getSelectedIndex() != -1)) {
           int s = NewTradeView.this.symbol.getSelectedIndex();
           if (s + 1 == NewTradeView.this.symbol.getSize())
             s = 0;
           else {
             s++;
           }
           NewTradeView.this.symbol.setSelectedIndex(s);
         }
         NewTradeView.this.symbolFieldChanged();
       }
     });
     this.symbol.setChangeListener(new FieldChangeListener()
     {
       public void fieldChanged(Field field, int context)
       {
         NewTradeView.this.symbolFieldChanged();
       }
     });
     this.sell.setChangeListener(new FieldChangeListener() {
       public void fieldChanged(Field field, int context) {
         NewTradeView.this.tradeTypeChanged("sell");
       }
     });
     this.buy.setChangeListener(new FieldChangeListener() {
       public void fieldChanged(Field field, int context) {
         NewTradeView.this.tradeTypeChanged("buy");
       }
     });
     this.units.setFocus();
   }
 
   private void createFields()
   {
     this.submit = new BitmapButtonField(Bitmap.getBitmapResource("submit-button-hover.png"), Bitmap.getBitmapResource("submit-button-p8.png"), "Submit", 12884967424L);
 
     this.symbol = new ColoredObjectChoiceField(16119285, "", null, 100, 23);
     this.quoteField = new QuoteEditField(0L, null, 0);
 
     this.sellBuyGroup = new RadioButtonGroup();
 
     this.operationFieldManager = new HorizontalFieldManager(1152921504606846976L);
     this.buy = new RadioButtonField("");
     this.sell = new RadioButtonField("");
 
     this.units = new ColoredEditField(3355443, " ", "", 14, 83886080L);
     this.tp = new TradeLimitEditField(3355443, " ", "", 12, 251658240L);
     this.sl = new TradeLimitEditField(3355443, " ", "", 12, 251658240L);
     this.ts = new TradeLimitEditField(3355443, " ", "", 12, 251658240L);
     this.lb = new TradeLimitEditField(3355443, " ", "", 12, 251658240L);
     this.ub = new TradeLimitEditField(3355443, " ", "", 12, 251658240L);
   }
 
   private void freeResourses() {
     Logger.log("free res bg");
 
     this.screen.getMainManager().setBackground(null);
   }
 
   private void setFonts() {
     this.ub.setFont(DefaultController.getComponentFont());
     this.lb.setFont(DefaultController.getComponentFont());
 
     this.tp.setFont(DefaultController.getComponentFont());
     this.ts.setFont(DefaultController.getComponentFont());
 
     this.sl.setFont(DefaultController.getComponentFont());
     this.units.setFont(DefaultController.getComponentFont());
 
     this.sell.setFont(DefaultController.getComponentFont().derive(0, 22));
     this.buy.setFont(DefaultController.getComponentFont().derive(0, 22));
 
     this.symbol.setFont(DefaultController.getComponentFont().derive(0, 22));
   }
 
   public boolean onClose() {
     stopQuoteUpdateThread();
     freeResourses();
     this.controller.popScreen(this.screen);
     this.screen = null;
     return true;
   }
 
   private void setBorders()
   {
   }
 
   private void quoteUpdates()
   {
     if (UiApplication.getUiApplication().getActiveScreen().equals(this.screen)) {
       String s = getListSymbols();
       if ((s != null) && (s.length() > 0)) {
         this.controller.quote(Model.getModel().getSessionToken(), s, null);
         this.controller.turnOnBacklight();
       }
     }
   }
 
   private String getListSymbols()
   {
     StringBuffer buffer = new StringBuffer();
 
     if ((this.symbol == null) || ((this.symbol != null) && (this.symbol.getSize() < 1))) return null;
 
     Quote[] quote = new Quote[this.symbol.getSize()];
     for (int i = 0; i < this.symbol.getSize(); i++) {
       Object o = this.symbol.getChoice(i);
       if ((o instanceof Quote)) {
         buffer.append(((Quote)o).getSymbol());
         buffer.append(',');
       }
 
     }
 
     if (buffer.length() > 1) {
       buffer = buffer.deleteCharAt(buffer.length() - 1);
     }
     return buffer.toString();
   }
 
   private void startQuoteUpdateThread() {
     Logger.log("new trade view quoteUpdateThread on UI EngineAttached start");
 
     if (this.quoteTimer == null) {
       this.quoteTimer = new Timer();
     }
 
     if (this.quoteTask == null)
       this.quoteTask = new TimerTask()
       {
         public void run()
         {
           NewTradeView.this.quoteUpdates();
         }
       };
     try {
       this.quoteTimer.schedule(this.quoteTask, 1000L, 5000L);
     }
     catch (IllegalStateException e) {
     }
   }
 
   private void stopQuoteUpdateThread() {
     Logger.log("new trade view quoteUpdateThread on UI EngineAttached cancelling");
     if (this.quoteTimer != null) {
       Logger.log("cancelling");
       if (this.quoteTask != null) {
         this.quoteTask.cancel();
       }
       this.quoteTimer.cancel();
       this.quoteTimer = null;
       this.quoteTask = null;
       Logger.log("Canceled");
     }
   }
 
   private void setSelectedQuote(String symbolS)
   {
     if (this.symbol != null) {
       int selected = 0;
       for (int i = 0; i < this.symbol.getSize(); i++) {
         Quote q = (Quote)this.symbol.getChoice(i);
         if ((q != null) && (q.getSymbol().equals(symbolS))) {
           selected = i;
           this.symbol.setSelectedIndex(selected);
           this.quoteField.setQuote(q);
           break;
         }
       }
     }
   }
}

